package sdfinal;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

public class ServidorArq extends Thread {

	private String nome;
	private int porta;
	private String diretorio;

	public ServidorArq(String nome) {
		this.nome = nome;
		this.porta = 20000 + new Random(this.getId()).nextInt(20000);
		this.diretorio = "src" + File.separator + "compartilhado" + File.separator + nome;
	}

	@Override
	public void run() {
		try {
			Thread multicastClient = new Thread(new ThreadBusca());
			multicastClient.start();
			ServerSocket welcomeSocket = new ServerSocket(porta);
			while (true) {
				Socket connectionSocket = welcomeSocket.accept();
				new Thread(new ThreadDownload(connectionSocket)).start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private class ThreadBusca implements Runnable {

		@Override
		public void run() {
			try {
				MulticastSocket mcs = new MulticastSocket(6000);
				InetAddress grp = InetAddress.getByName("239.0.0.1");
				mcs.joinGroup(grp);
				while (true) {
					byte rec[] = new byte[256];
					final DatagramPacket pkg = new DatagramPacket(rec, rec.length);
					mcs.receive(pkg);
					final String arquivo = new String(pkg.getData(), 0, pkg.getLength());

					new Thread(new Runnable() {
						@Override
						public void run() { 
							File f = new File(diretorio + File.separator + arquivo);
							if (f.exists()) {
								try {
									DatagramSocket clientSocket = new DatagramSocket();
									byte[] sendData = (nome + "," + porta).getBytes();
									DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,
											pkg.getAddress(), 7000);
									clientSocket.send(sendPacket);
								} catch (IOException e) {
									e.printStackTrace();
								}
							}
						}
					}).start();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public class ThreadDownload implements Runnable {

		private Socket connectionSocket;

		public ThreadDownload(Socket connectionSocket) {
			this.connectionSocket = connectionSocket;
		}

		@Override
		public void run() {
			try {
				BufferedReader inFromClient = new BufferedReader(new InputStreamReader(
						connectionSocket.getInputStream()));
				DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
				String nomeArq = diretorio + File.separator + inFromClient.readLine();

				File arquivo = new File(nomeArq);
				FileInputStream file = new FileInputStream(arquivo);

				byte[] bytes = new byte[(int) arquivo.length()];
				file.read(bytes, 0, bytes.length);
				outToClient.write(bytes, 0, bytes.length);
				outToClient.flush();

				outToClient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}